package com.cencat.user.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.cencat.common.response.PageResponse;
import com.cencat.user.dto.RolePermissionDTO;
import com.cencat.user.dto.RolePermissionQueryDTO;
import com.cencat.user.service.RolePermissionService;
import com.cencat.user.vo.RolePermissionVO;
import com.cencat.common.response.ApiResponse;
import com.cencat.common.exception.BusinessException;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 角色权限关联管理控制器
 * @author cencat
 * @since 2024-01-01
 */
@RestController
@RequestMapping("/api/role-permission")
@Tag(name = "角色权限关联管理", description = "角色权限关联管理相关接口")
@Slf4j
public class RolePermissionController {

    @Autowired
    private RolePermissionService rolePermissionService;

    /**
     * 分配角色权限
     * @param dto 角色权限DTO
     * @return 操作结果
     */
    @PostMapping("/assign")
    @Operation(summary = "分配角色权限", description = "为角色分配权限")
    public ApiResponse<Boolean> assignRolePermissions(
            @Valid @RequestBody RolePermissionDTO dto) {
        try {
            Boolean result = rolePermissionService.assignRolePermissions(dto);
            return ApiResponse.success(result);
        } catch (BusinessException e) {
            log.error("分配角色权限失败: {}", e.getMessage());
            return ApiResponse.error(e.getErrorCode());
        }
    }

    /**
     * 移除角色权限
     * @param dto 角色权限DTO
     * @return 操作结果
     */
    @PostMapping("/remove")
    @Operation(summary = "移除角色权限", description = "移除角色的权限")
    public ApiResponse<Boolean> removeRolePermissions(
            @Valid @RequestBody RolePermissionDTO dto) {
        try {
            Boolean result = rolePermissionService.removeRolePermissions(dto);
            return ApiResponse.success(result);
        } catch (BusinessException e) {
            log.error("移除角色权限失败: {}", e.getMessage());
            return ApiResponse.error(e.getErrorCode());
        }
    }

    /**
     * 更新角色权限
     * @param dto 角色权限DTO
     * @return 操作结果
     */
    @PutMapping("/update")
    @Operation(summary = "更新角色权限", description = "更新角色的权限配置")
    public ApiResponse<Boolean> updateRolePermissions(
            @Valid @RequestBody RolePermissionDTO dto) {
        try {
            Boolean result = rolePermissionService.updateRolePermissions(dto);
            return ApiResponse.success(result);
        } catch (BusinessException e) {
            log.error("更新角色权限失败: {}", e.getMessage());
            return ApiResponse.error(e.getErrorCode());
        }
    }

    /**
     * 根据角色ID查询权限列表
     * @param roleId 角色ID
     * @param tenantId 租户ID
     * @return 权限列表
     */
    @GetMapping("/permissions/{roleId}")
    @Operation(summary = "查询角色权限列表", description = "根据角色ID查询权限列表")
    public ApiResponse<List<RolePermissionVO.PermissionInfo>> getPermissionsByRoleId(
            @Parameter(description = "角色ID", required = true)
            @PathVariable @Min(1) Long roleId,
            @Parameter(description = "租户ID", required = true)
            @RequestParam @NotNull Long tenantId) {
        try {
            List<RolePermissionVO.PermissionInfo> result = rolePermissionService.getPermissionsByRoleId(roleId, tenantId);
            return ApiResponse.success(result);
        } catch (BusinessException e) {
            log.error("查询角色权限列表失败: {}", e.getMessage());
            return ApiResponse.error(e.getErrorCode());
        }
    }

    /**
     * 根据权限ID查询角色列表
     * @param permissionId 权限ID
     * @param tenantId 租户ID
     * @return 角色列表
     */
    @GetMapping("/roles/{permissionId}")
    @Operation(summary = "查询权限角色列表", description = "根据权限ID查询角色列表")
    public ApiResponse<List<RolePermissionVO>> getRolesByPermissionId(
            @Parameter(description = "权限ID", required = true)
            @PathVariable @Min(1) Long permissionId,
            @Parameter(description = "租户ID", required = true)
            @RequestParam @NotNull Long tenantId) {
        try {
            List<RolePermissionVO> result = rolePermissionService.getRolesByPermissionId(permissionId, tenantId);
            return ApiResponse.success(result);
        } catch (BusinessException e) {
            log.error("查询权限角色列表失败: {}", e.getMessage());
            return ApiResponse.error(e.getErrorCode());
        }
    }

    /**
     * 分页查询角色权限关联
     * @param queryDTO 查询条件
     * @return 分页结果
     */
    @PostMapping("/page")
    @Operation(summary = "分页查询角色权限关联", description = "分页查询角色权限关联信息")
    public ApiResponse<PageResponse<RolePermissionVO>> getRolePermissionPage(
            @Valid @RequestBody RolePermissionQueryDTO queryDTO) {
        try {
            PageResponse<RolePermissionVO> rolePermissionPage = rolePermissionService.getRolePermissionPage(queryDTO);
            return ApiResponse.success(rolePermissionPage);
        } catch (BusinessException e) {
            log.error("分页查询角色权限关联失败: {}", e.getMessage());
            return ApiResponse.error(e.getErrorCode());
        }
    }

    /**
     * 查询角色权限关联列表
     * @param queryDTO 查询条件
     * @return 角色权限关联列表
     */
    @PostMapping("/list")
    @Operation(summary = "查询角色权限关联列表", description = "查询角色权限关联列表")
    public ApiResponse<List<RolePermissionVO>> getRolePermissionList(
            @Valid @RequestBody RolePermissionQueryDTO queryDTO) {
        try {
            List<RolePermissionVO> result = rolePermissionService.getRolePermissionList(queryDTO);
            return ApiResponse.success(result);
        } catch (BusinessException e) {
            log.error("查询角色权限关联列表失败: {}", e.getMessage());
            return ApiResponse.error(e.getErrorCode());
        }
    }

    /**
     * 检查角色是否拥有权限
     * @param roleId 角色ID
     * @param permissionId 权限ID
     * @param tenantId 租户ID
     * @return 是否拥有权限
     */
    @GetMapping("/check/{roleId}/{permissionId}")
    @Operation(summary = "检查角色权限", description = "检查角色是否拥有指定权限")
    public ApiResponse<Boolean> checkRoleHasPermission(
            @Parameter(description = "角色ID", required = true)
            @PathVariable @Min(1) Long roleId,
            @Parameter(description = "权限ID", required = true)
            @PathVariable @Min(1) Long permissionId,
            @Parameter(description = "租户ID", required = true)
            @RequestParam @NotNull Long tenantId) {
        try {
            Boolean result = rolePermissionService.checkRoleHasPermission(roleId, permissionId, tenantId);
            return ApiResponse.success(result);
        } catch (BusinessException e) {
            log.error("检查角色权限失败: {}", e.getMessage());
            return ApiResponse.error(e.getErrorCode());
        }
    }

    /**
     * 检查角色是否拥有权限编码
     * @param roleId 角色ID
     * @param permissionCode 权限编码
     * @param tenantId 租户ID
     * @return 是否拥有权限
     */
    @GetMapping("/check-code/{roleId}")
    @Operation(summary = "检查角色权限编码", description = "检查角色是否拥有指定权限编码")
    public ApiResponse<Boolean> checkRoleHasPermissionCode(
            @Parameter(description = "角色ID", required = true)
            @PathVariable @Min(1) Long roleId,
            @Parameter(description = "权限编码", required = true)
            @RequestParam @NotNull String permissionCode,
            @Parameter(description = "租户ID", required = true)
            @RequestParam @NotNull Long tenantId) {
        try {
            Boolean result = rolePermissionService.checkRoleHasPermissionCode(roleId, permissionCode, tenantId);
            return ApiResponse.success(result);
        } catch (BusinessException e) {
            log.error("检查角色权限编码失败: {}", e.getMessage());
            return ApiResponse.error(e.getErrorCode());
        }
    }

    /**
     * 查询角色权限详情
     * @param roleId 角色ID
     * @param tenantId 租户ID
     * @return 角色权限详情
     */
    @GetMapping("/detail/{roleId}")
    @Operation(summary = "查询角色权限详情", description = "查询角色权限详细信息")
    public ApiResponse<RolePermissionVO> getRolePermissionDetail(
            @Parameter(description = "角色ID", required = true)
            @PathVariable @Min(1) Long roleId,
            @Parameter(description = "租户ID", required = true)
            @RequestParam @NotNull Long tenantId) {
        try {
            RolePermissionVO result = rolePermissionService.getRolePermissionDetail(roleId, tenantId);
            return ApiResponse.success(result);
        } catch (BusinessException e) {
            log.error("查询角色权限详情失败: {}", e.getMessage());
            return ApiResponse.error(e.getErrorCode());
        }
    }

    /**
     * 批量分配角色权限
     * @param request 批量分配请求
     * @return 操作结果
     */
    @PostMapping("/batch-assign")
    @Operation(summary = "批量分配角色权限", description = "批量为多个角色分配权限")
    public ApiResponse<Boolean> batchAssignRolePermissions(
            @Valid @RequestBody BatchRolePermissionRequest request) {
        try {
            Boolean result = rolePermissionService.batchAssignRolePermissions(
                request.getRoleIds(), request.getPermissionIds(), 
                request.getTenantId(), request.getOperatorId());
            return ApiResponse.success(result);
        } catch (BusinessException e) {
            log.error("批量分配角色权限失败: {}", e.getMessage());
            return ApiResponse.error(e.getErrorCode());
        }
    }

    /**
     * 批量移除角色权限
     * @param request 批量移除请求
     * @return 操作结果
     */
    @PostMapping("/batch-remove")
    @Operation(summary = "批量移除角色权限", description = "批量移除多个角色的权限")
    public ApiResponse<Boolean> batchRemoveRolePermissions(
            @Valid @RequestBody BatchRolePermissionRequest request) {
        try {
            Boolean result = rolePermissionService.batchRemoveRolePermissions(
                request.getRoleIds(), request.getPermissionIds(), request.getTenantId());
            return ApiResponse.success(result);
        } catch (BusinessException e) {
            log.error("批量移除角色权限失败: {}", e.getMessage());
            return ApiResponse.error(e.getErrorCode());
        }
    }

    /**
     * 复制角色权限
     * @param request 复制权限请求
     * @return 操作结果
     */
    @PostMapping("/copy")
    @Operation(summary = "复制角色权限", description = "将源角色的权限复制到目标角色")
    public ApiResponse<Boolean> copyRolePermissions(
            @Valid @RequestBody CopyRolePermissionRequest request) {
        try {
            Boolean result = rolePermissionService.copyRolePermissions(
                request.getSourceRoleId(), request.getTargetRoleId(), 
                request.getTenantId(), request.getOperatorId());
            return ApiResponse.success(result);
        } catch (BusinessException e) {
            log.error("复制角色权限失败: {}", e.getMessage());
            return ApiResponse.error(e.getErrorCode());
        }
    }

    /**
     * 清空角色权限
     * @param roleId 角色ID
     * @param tenantId 租户ID
     * @return 操作结果
     */
    @DeleteMapping("/clear/{roleId}")
    @Operation(summary = "清空角色权限", description = "清空指定角色的所有权限")
    public ApiResponse<Boolean> clearRolePermissions(
            @Parameter(description = "角色ID", required = true)
            @PathVariable @Min(1) Long roleId,
            @Parameter(description = "租户ID", required = true)
            @RequestParam @NotNull Long tenantId) {
        try {
            Boolean result = rolePermissionService.clearRolePermissions(roleId, tenantId);
            return ApiResponse.success(result);
        } catch (BusinessException e) {
            log.error("清空角色权限失败: {}", e.getMessage());
            return ApiResponse.error(e.getErrorCode());
        }
    }

    /**
     * 同步角色权限
     * @param request 同步权限请求
     * @return 操作结果
     */
    @PostMapping("/sync")
    @Operation(summary = "同步角色权限", description = "同步角色的权限配置")
    public ApiResponse<Boolean> syncRolePermissions(
            @Valid @RequestBody SyncRolePermissionRequest request) {
        try {
            Boolean result = rolePermissionService.syncRolePermissions(
                request.getRoleId(), request.getPermissionIds(), 
                request.getTenantId(), request.getOperatorId());
            return ApiResponse.success(result);
        } catch (BusinessException e) {
            log.error("同步角色权限失败: {}", e.getMessage());
            return ApiResponse.error(e.getErrorCode());
        }
    }

    /**
     * 统计角色权限关联数量
     * @param tenantId 租户ID
     * @return 关联数量
     */
    @GetMapping("/count")
    @Operation(summary = "统计角色权限关联数量", description = "统计租户下的角色权限关联总数")
    public ApiResponse<Long> countRolePermissions(
            @Parameter(description = "租户ID", required = true)
            @RequestParam @NotNull Long tenantId) {
        try {
            Long result = rolePermissionService.countRolePermissions(tenantId);
            return ApiResponse.success(result);
        } catch (BusinessException e) {
            log.error("统计角色权限关联数量失败: {}", e.getMessage());
            return ApiResponse.error(e.getErrorCode());
        }
    }

    /**
     * 统计角色的权限数量
     * @param roleId 角色ID
     * @param tenantId 租户ID
     * @return 权限数量
     */
    @GetMapping("/count/permissions/{roleId}")
    @Operation(summary = "统计角色权限数量", description = "统计指定角色的权限数量")
    public ApiResponse<Long> countPermissionsByRoleId(
            @Parameter(description = "角色ID", required = true)
            @PathVariable @Min(1) Long roleId,
            @Parameter(description = "租户ID", required = true)
            @RequestParam @NotNull Long tenantId) {
        try {
            Long result = rolePermissionService.countPermissionsByRoleId(roleId, tenantId);
            return ApiResponse.success(result);
        } catch (BusinessException e) {
            log.error("统计角色权限数量失败: {}", e.getMessage());
            return ApiResponse.error(e.getErrorCode());
        }
    }

    /**
     * 统计权限的角色数量
     * @param permissionId 权限ID
     * @param tenantId 租户ID
     * @return 角色数量
     */
    @GetMapping("/count/roles/{permissionId}")
    @Operation(summary = "统计权限角色数量", description = "统计指定权限的角色数量")
    public ApiResponse<Long> countRolesByPermissionId(
            @Parameter(description = "权限ID", required = true)
            @PathVariable @Min(1) Long permissionId,
            @Parameter(description = "租户ID", required = true)
            @RequestParam @NotNull Long tenantId) {
        try {
            Long result = rolePermissionService.countRolesByPermissionId(permissionId, tenantId);
            return ApiResponse.success(result);
        } catch (BusinessException e) {
            log.error("统计权限角色数量失败: {}", e.getMessage());
            return ApiResponse.error(e.getErrorCode());
        }
    }

    /**
     * 批量角色权限请求类
     */
    public static class BatchRolePermissionRequest {
        @NotNull(message = "角色ID列表不能为空")
        private List<Long> roleIds;
        
        @NotNull(message = "权限ID列表不能为空")
        private List<Long> permissionIds;
        
        @NotNull(message = "租户ID不能为空")
        private Long tenantId;
        
        private Long operatorId;

        // Getters and Setters
        public List<Long> getRoleIds() { return roleIds; }
        public void setRoleIds(List<Long> roleIds) { this.roleIds = roleIds; }
        public List<Long> getPermissionIds() { return permissionIds; }
        public void setPermissionIds(List<Long> permissionIds) { this.permissionIds = permissionIds; }
        public Long getTenantId() { return tenantId; }
        public void setTenantId(Long tenantId) { this.tenantId = tenantId; }
        public Long getOperatorId() { return operatorId; }
        public void setOperatorId(Long operatorId) { this.operatorId = operatorId; }
    }

    /**
     * 复制角色权限请求类
     */
    public static class CopyRolePermissionRequest {
        @NotNull(message = "源角色ID不能为空")
        private Long sourceRoleId;
        
        @NotNull(message = "目标角色ID不能为空")
        private Long targetRoleId;
        
        @NotNull(message = "租户ID不能为空")
        private Long tenantId;
        
        private Long operatorId;

        // Getters and Setters
        public Long getSourceRoleId() { return sourceRoleId; }
        public void setSourceRoleId(Long sourceRoleId) { this.sourceRoleId = sourceRoleId; }
        public Long getTargetRoleId() { return targetRoleId; }
        public void setTargetRoleId(Long targetRoleId) { this.targetRoleId = targetRoleId; }
        public Long getTenantId() { return tenantId; }
        public void setTenantId(Long tenantId) { this.tenantId = tenantId; }
        public Long getOperatorId() { return operatorId; }
        public void setOperatorId(Long operatorId) { this.operatorId = operatorId; }
    }

    /**
     * 同步角色权限请求类
     */
    public static class SyncRolePermissionRequest {
        @NotNull(message = "角色ID不能为空")
        private Long roleId;
        
        private List<Long> permissionIds;
        
        @NotNull(message = "租户ID不能为空")
        private Long tenantId;
        
        private Long operatorId;

        // Getters and Setters
        public Long getRoleId() { return roleId; }
        public void setRoleId(Long roleId) { this.roleId = roleId; }
        public List<Long> getPermissionIds() { return permissionIds; }
        public void setPermissionIds(List<Long> permissionIds) { this.permissionIds = permissionIds; }
        public Long getTenantId() { return tenantId; }
        public void setTenantId(Long tenantId) { this.tenantId = tenantId; }
        public Long getOperatorId() { return operatorId; }
        public void setOperatorId(Long operatorId) { this.operatorId = operatorId; }
    }
}